package hamaster.jpbc.gui;

import hamaster.jpbc.gui.callback.AsynchronousCallback;
import hamaster.jpbc.mgr.SymmetricEncryptManager;
import hamaster.jpbc.pbc.PBC;
import hamaster.jpbc.pbc.PBCDriver;
import hamaster.jpbc.pbs.PBS;
import hamaster.jpbc.pbs.PersonalParameter;
import hamaster.jpbc.pbs.Signature;
import hamaster.jpbc.util.Hash;
import it.unisa.dia.gas.jpbc.Element;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Properties;

import javax.swing.JOptionPane;

class SignatureVerifyThread implements Runnable {

	private File signed;
	private Properties metadata;
	private AsynchronousCallback callback;

	public SignatureVerifyThread(File signed, Properties metadata, AsynchronousCallback callback) {
		this.signed = signed;
		this.metadata = metadata;
		this.callback = callback;
	}

	@Override
	public void run() {
		PBC pbc = PBC.instance();
		byte[] hash;
		try {
			hash = Hash.sha1(signed, callback);
		} catch (IOException e) {
			String format = Messages.getString("VerifyPanel.connotHash"); //$NON-NLS-1$
			callback.message(String.format(format, signed.getName()), JOptionPane.ERROR_MESSAGE);
			return;
		}
		String hashStr = metadata.getProperty(SymmetricEncryptManager.SIGNATURE_PREFIX + "." + Signature.HASH_POSTFIX); //$NON-NLS-1$
		byte[] elem = PBCDriver.unhex(hashStr);
		if (!Arrays.equals(hash, elem)) {
			String format = Messages.getString("VerifyPanel.badFile"); //$NON-NLS-1$
			callback.message(String.format(format, signed.getName(), PBCDriver.hex(hash), hashStr), VerifyPanel.VERIFY_RESULT);
			return;
		}
		Element hashElem = pbc.getPairing().getZr().newElement();
		hashElem.setFromBytes(elem);
		Signature signature = new Signature();
		signature.setFromProperties(metadata, SymmetricEncryptManager.SIGNATURE_PREFIX);
		PersonalParameter parameter = new PersonalParameter();
		parameter.setFromProperties(metadata, SymmetricEncryptManager.PERSONAL_PARAMETER_PREFIX);
		PBS pbs = PBS.instance(pbc);
		boolean result = pbs.verify(signature, parameter);
		String content;
		String format;
		if (result) {
			format = Messages.getString("VerifyPanel.verifyPassed"); //$NON-NLS-1$
			content = String.format(format, signed.getName(), metadata.getProperty(SymmetricEncryptManager.PLAIN_FILE_LENGTH), hashStr, parameter.getrIDString());
		} else {
			format = Messages.getString("VerifyPanel.verifyFailed"); //$NON-NLS-1$
			content = String.format(format, signed.getName(), parameter.getrIDString(), hashStr);
		}
		callback.progressUpdated(100);
		callback.message(content, VerifyPanel.VERIFY_RESULT);
	}
}
